#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"

void jpeg_start_compress( j_compress_ptr cinfo, wxjpeg_boolean write_all_tables ) {
  if( cinfo->global_state != CSTATE_START )
  { ERREXIT1( cinfo, JERR_BAD_STATE, cinfo->global_state ); }
  if( write_all_tables )
  { jpeg_suppress_tables( cinfo, FALSE ); }
  ( *cinfo->err->reset_error_mgr )( ( j_common_ptr ) cinfo );
  ( *cinfo->dest->init_destination )( cinfo );
  jinit_compress_master( cinfo );
  ( *cinfo->master->prepare_for_pass )( cinfo );
  cinfo->next_scanline = 0;
  cinfo->global_state = ( cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING );
}

JDIMENSION jpeg_write_scanlines( j_compress_ptr cinfo, JSAMPARRAY scanlines,
                                 JDIMENSION num_lines ) {
  JDIMENSION row_ctr, rows_left;
  if( cinfo->global_state != CSTATE_SCANNING )
  { ERREXIT1( cinfo, JERR_BAD_STATE, cinfo->global_state ); }
  if( cinfo->next_scanline >= cinfo->image_height )
  { WARNMS( cinfo, JWRN_TOO_MUCH_DATA ); }
  if( cinfo->progress != NULL ) {
    cinfo->progress->pass_counter = ( long ) cinfo->next_scanline;
    cinfo->progress->pass_limit = ( long ) cinfo->image_height;
    ( *cinfo->progress->progress_monitor )( ( j_common_ptr ) cinfo );
  }
  if( cinfo->master->call_pass_startup ) {
    ( *cinfo->master->pass_startup )( cinfo );
  }
  rows_left = cinfo->image_height - cinfo->next_scanline;
  if( num_lines > rows_left )
  { num_lines = rows_left; }
  row_ctr = 0;
  ( *cinfo->main->process_data )( cinfo, scanlines, &row_ctr, num_lines );
  cinfo->next_scanline += row_ctr;
  return row_ctr;
}

JDIMENSION jpeg_write_raw_data( j_compress_ptr cinfo, JSAMPIMAGE data, JDIMENSION num_lines ) {
  JDIMENSION lines_per_iMCU_row;
  if( cinfo->global_state != CSTATE_RAW_OK )
  { ERREXIT1( cinfo, JERR_BAD_STATE, cinfo->global_state ); }
  if( cinfo->next_scanline >= cinfo->image_height ) {
    WARNMS( cinfo, JWRN_TOO_MUCH_DATA );
    return 0;
  }
  if( cinfo->progress != NULL ) {
    cinfo->progress->pass_counter = ( long ) cinfo->next_scanline;
    cinfo->progress->pass_limit = ( long ) cinfo->image_height;
    ( *cinfo->progress->progress_monitor )( ( j_common_ptr ) cinfo );
  }
  if( cinfo->master->call_pass_startup )
  { ( *cinfo->master->pass_startup )( cinfo ); }
  lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
  if( num_lines < lines_per_iMCU_row )
  { ERREXIT( cinfo, JERR_BUFFER_SIZE ); }
  if( !( *cinfo->coef->compress_data )( cinfo, data ) ) {
    return 0;
  }
  cinfo->next_scanline += lines_per_iMCU_row;
  return lines_per_iMCU_row;
}
